The basic flow for the member join process is as follows:

  1. Start the join process and generate a cart_id.
  2. Add a member to the cart with personal information and handle duplicates if there are any returned.
  3. Repeat step 2 for as many members as there are in the cart.
  4. Review
  5. Accept membership agreements (if required)
  6. Collect payment information (if payment is required)
  7. Check out

Concepts

  • A membership type defines the type of membership and the rate. Example: 2 Adults + 1 Child for $80/month.
  • A member is a single person.
  • A unit is a collection of people, usually a household.
  • A cart is a temporary storage mechanism for building up the members in a unit and checking out at once.
  • A renewal is when an inactive unit signs up for an active membership.

Full Example

Step 1: Collect Data

Step 2: Start Join Process

NOTE: If you want to renew an inactive unit, please refer to the Membership Renewal Tutorial

Use the Create a Cart API call to create a new cart. This “Create a Cart” call is exclusive to Member Join. If attempting to create a cart for programs, packages, or child care and camp, please reference the Program Registration Tutorial.

You will use the cart_id in the response for subsequent calls.

Request:

POST /v3/membership/join
{
  "membership_type_id": "MT12345"
}

Response:

{
  "cart_id": "2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94",
  "links": [
    {
      "rel": "review",
      "href": "/v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94"
    }
  ]
}

Step 3a: (Optional) Get Member Questions

This gets the list of member questions that are defined by the client. age_group_id is required because the questions could vary by adult or child depending on how the system is configured. Use the List age groups API call to get a list of age groups defined by the client. Alternatively, you may use the value of any_adult or any_child if you do not wish to specify a granular age_group_id.

Request:

GET /v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/member_questions?age_group_id=any_adult

Step 3b: Add Member

Use the Add member to cart API call to add members to the cart.

See note in step 3a about age_group_id as a required parameter.

Request:

POST /v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/members?age_group_id=any_adult
{
  "name": {
    "first": "John",
    "last": "Doe"
  },
  "email": "john.doe@example.org",
  "gender": "M",
  "birth_date": "1980-01-01",
  "primary_address": {
    "line1": "555 Some Dr.",
    "city": "Homewood",
    "state": "AL",
    "zip": "35209",
    "country": "US"
  },
  "primary_phone": {
    "phone": "111-222-3333"
  },
  "race": "W",
  "emergency_contact": {
    "first": "Mighty",
    "last": "Mouse"
  },
  "emergency_phone": {
    "phone": "333-222-1111"
  },
  "password": {
    "password": "Password1234",
    "password_confirm": "Password1234"
  }
}

Step 3c: Handle Duplicates

If the response contains a duplicates collection, then this means that the system has found possible duplicate members. In order to maintain the data quality of the client, you must have the user review the duplicates in some form and acknowledge that the duplicates have been reviewed if you want to continue adding the member.

The response contains a string in duplicates.ack_duplicates_token which must be passed to the previous POST in order to continue.

Response:

{
  "errors": [
    {
      "key": "duplicates",
      "message": "We've matched your information to another account."
    }
  ],
  "duplicates": {
    "ack_duplicates_token": "58bf368aa7cfedaf0384468a1cfdbc6db8d9c852",
    "matches": [
      {
        "match_percent": 0.85,
        "member_id": "300032442-01",
        "name": {
          "first": "john",
          "last": "doe"
        },
        "email": "jdoe@somewhere.com",
        "birth_date": "1980-01-01",
        "primary_address": {
          "zip": ""
        },
        "primary_phone": {
          "phone": ""
        }
      },
      {
        "match_percent": 0.75,
        "member_id": "300181278-01",
        "name": {
          "first": "John",
          "last": "Doe"
        },
        "email": "test@test.com",
        "birth_date": "1980-05-21",
        "gender": "M",
        "primary_address": {
          "zip": "35209"
        },
        "primary_phone": {
          "phone": "111-2222"
        }
      }
    ]
  }
}

Now you must take the ack_duplicates_token and re-run the previous request but include this value in the query string.

Request:

POST /v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/members?age_group_id=any_adult&ack_duplicates_token=58bf368aa7cfedaf0384468a1cfdbc6db8d9c852
{
  ...
}

Response:

{
  "links": [
    {
      "rel": "review",
      "href": "/v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94"
    },
    {
      "rel": "member",
      "href": "/v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/members/a481dfc4-34dd-4b23-af8d-d900c8b14f4c"
    }
  ],
  "member_guid": "a481dfc4-34dd-4b23-af8d-d900c8b14f4c"
}

Step 3d: Add-Ons

Use the Get Add-Ons API call to see eligible add-ons that can be added to the membership.

Use the Save Add-Ons API call to add add-ons to the current cart.

Use the Remove Add-Ons API call to remove add-ons from the current cart.

Use the Add a recurring donation API call to add a recurring donation to the current cart.

Step 4: Review

Use the Get review information to get the state of the cart: selected membership type, list of members in the cart, etc.

Request:

GET /v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94

Response:

{
  "recurring_fees": [
    {
      "line_item_id": "71481",
      "short_description": "Membership Due",
      "type": "membership_fee",
      "unit_price": 50,
      "quantity": 1,
      "extended_price": 50,
      "can_remove": false,
      "discounts": [],
      "taxes": []
    }
  ],
  "one_time_fees": [
    {
      "line_item_id": "78abd3d4-8479-49cf-a1ec-1ff7b8a5991d",
      "short_description": "Join Fee",
      "type": "join",
      "unit_price": 75,
      "quantity": 1,
      "due_today_amount": 75,
      "can_remove": false,
      "discounts": []
    },
    {
      "line_item_id": "f82159ad-5c7a-4686-83e9-8981731b329a",
      "short_description": "Prorated Dues (Apr 5 thru Apr 27)",
      "type": "membership",
      "unit_price": 38,
      "quantity": 1,
      "due_today_amount": 38,
      "can_remove": false,
      "discounts": []
    },
    {
      "line_item_id": "9ed5e107-0689-4370-9285-10f50f847030",
      "short_description": "Membership Due (Apr 2018 - May 2018)",
      "type": "membership",
      "unit_price": 50,
      "quantity": 1,
      "due_today_amount": 0,
      "can_remove": false,
      "discounts": []
    }
  ],
  "version": "AAAAAAmku/Y=",
  "membership_type": {
    "id": "MT12345",
    "name": "My Membership Type",
    "is_auto_renew": true,
    "term": {
      "description": "Monthly",
      "id": 0,
      "months_in_term": 1
    }
  },
  "applied_discount_group_ids": [],
  "home_branch": {
    "id": "B27",
    "name": "Blocker/Norfolk Family YMCA",
    "full_address": "312 West Bute Street Norfolk, VA 23510 ",
    "phone": "(757) 555-5555"
  },
  "billing_cycle": {
    "name": "Monthly",
    "months_in_cycle": 1
  },
  "billing_cyles": [
    {
      "name": "Monthly",
      "months_in_cycle": 1
    },
    {
      "name": "Quarterly",
      "months_in_cycle": 3
    },
    {
      "name": "Semi Annual",
      "months_in_cycle": 6
    },
    {
      "name": "Annual",
      "months_in_cycle": 12
    }
  ],
  "draft_day": 28,
  "draft_days": [
    {
      "day": 15,
      "description": "15th"
    },
    {
      "day": 28,
      "description": "28th"
    },
    {
      "day": 30,
      "description": "30th"
    }
  ],
  "auto_renew": true,
  "next_process_date": "2018-05-01T00:00:00.0000000",
  "expiration_date": "2001-01-01T00:00:00.0000000",
  "renew": true,
  "members": [
    {
      "member_guid": "a481dfc4-34dd-4b23-af8d-d900c8b14f4c",
      "first_name": "John",
      "last_name": "Doe",
      "primary_member": true,
      "active": true,
      "age_group": {
        "id": "any_adult",
        "name": "Adult",
        "min_age": 0,
        "max_age": 999,
        "description": "",
        "category": "any_adult"
      },
      "email": "john.doe@example.org",
      "can_change_status": true,
      "can_remove": false,
      "birth_date": "1980-01-01T00:00:00.0000000"
    }
  ],
  "age_group_rules": {
    "valid": true,
    "rules": []
  },
  "allow_payment": true,
  "valid": true,
  "errors": [],
  "steps": {
    "required": ["agreements"]
  }
}

Step 4a: (Optional) Edit Member

First, get the questions and answers for the member with member_guid of a481dfc4-34dd-4b23-af8d-d900c8b14f4c using the get-member-in-cart API call.

Request:

GET /v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/members/a481dfc4-34dd-4b23-af8d-d900c8b14f4c

Response:

{
  "questions": {
    ...
  },
  "answers": {
    "name": {
      "first": "John",
      "last": "Doe"
    },
    "email": "john.doe@example.org",
    "gender": "M",
    "birth_date": "1980-01-01",
    "primary_address": {
      "line1": "111 Some Dr.",
      "city": "Homewood",
      "state": "AL",
      "zip": "35209",
      "country": "US"
    },
    "primary_phone": {
      "phone": "111-222-3333"
    },
    "race": "W",
    "emergency_contact": {
      "first": "Mighty",
      "last": "Mouse"
    },
    "emergency_phone": {
      "phone": "333-222-1111"
    },
    "password": {
      "password": "Password1234",
      "password_confirm": "Password1234"
    }
  }
}

Next, save new answers for the member using the get-member-in-cart API call.

Request:

PUT /v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/members/a481dfc4-34dd-4b23-af8d-d900c8b14f4c
{
  "name": {
    "first": "Johnny",
    "last": "Does"
  },
  "email": "john.doe@example.org",
  "gender": "M",
  "birth_date": "1980-01-01",
  "primary_address": {
    "line1": "111 Some Dr.",
    "city": "Homewood",
    "state": "AL",
    "zip": "35209",
    "country": "US"
  },
  "primary_phone": {
    "phone": "111-222-3333"
  },
  "race": "W",
  "emergency_contact": {
    "first": "Mighty",
    "last": "Mouse"
  },
  "emergency_phone": {
    "phone": "333-222-1111"
  },
  "password": {
    "password": "Password1234",
    "password_confirm": "Password1234"
  }
}

Step 4a: (Optional) Delete Members

Use a list of one or more member guids to delete them from the cart using the remove-member-from-cart API call.

Request:

DELETE /v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/members
{
  "member_guids": ["a481dfc4-34dd-4b23-af8d-d900c8b14f4c"]
}

Step 5: (Optional) Accept Membership Agreements

If the Get review information API call has agreements in steps.required, this means that membership agreement(s) must be accepted before checking out.

Use the Get membership agreements API call to get a list of agreements that must be accepted.

Request:

GET /v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/agreements

Response:

{
  "agreements": [
    {
      "agreement_id": "W1299",
      "title": "This is the title of the agreement",
      "body": "lorem ipsum...",
      "accepted": false
    }
  ]
}

Next, use the Accept membership agreements API call to accept and sign the membership agreements:

Request:

PUT /v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/agreements
{
  "agreement_ids": [
    "W1299"
  ],
  "signee_name": "John Doe"
}

Step 6a: Checkout (without payment)

Use the Checkout API call in order to check out and finalize the join/renewal.

In order to checkout without payment, the payment_method_amount must be 0, and each amount in the line_item_payments collection must be 0. The version value must be the same as the last value from the Get review information API call.

Request:

POST /v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/checkout
{
  "version": "AAAAAAmit1o=",
  "customer": {
    "name": "John Doe",
    "email": "john.doe@example.org"
  },
  "payment_info": [
    {
      "payment_method_amount": 0.0,
      "line_item_payments": [
        {
          "line_item_id": "aaaaaaaa-0b27-48c7-b682-48e5206e0be3",
          "amount": 0,
          "schedule_remaining": false
        },
        {
          "line_item_id": "bbbbbbbb-0b27-48c7-b682-48e5206e0be3",
          "amount": 0,
          "schedule_remaining": false
        },
      ]
    }
  ]
}

Successful Response:

{
  "success": true,
  "links": [
    {
      "rel": "receipt",
      "href": "/v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/receipt"
    },
    {
      "rel": "unit",
      "href": "/v3/units/300181530"
    }
  ],
  "unit_id": "300181530"
}

Step 6b: Checkout (with Daxko Operations payment page)

This is the preferred method to capture payment information and check out.

Use the One-time Link to generate a one-time link (that expires in 10 minutes) that you will redirect your user to Daxko Operations Online in order to capture payment information and complete the checkout process.

Request:

POST /v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/one_time_link
{
  "redirect_uri": "https://example.org/my_success_landing_page",
  "step": "pay",
  "header": "show",
  "nav": "hide",
  "footer": "hide"
}

Response

{
  "url": "https://operations.daxko.com/online/2014/cart/redirector.mvc?code=_qNGKCKowkSmHDzCY6y8zT4bxCCD2LZgQN8m4ko_6E0&__header=show&__footer=hide&__nav=hide"
}

Step 6c: Checkout (with new payment method using javascript tokenization)

In order to pay with a new payment method, it must be tokenized using our payment tokens JavaScript library. First, see the Payment Tokenization tutorial on how to generate a payment token. The output will be a value that looks like PT3raaMpFPXEsmVexb5JOF3Zpff2TmtENJ_yZkLTudSrY and will be used in the checkout call.

Request:

POST /v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/checkout
{
  "version": "AAAAAAmit1o=",
  "customer": {
    "name": "John Doe",
    "email": "john.doe@example.org"
  },
  "payment_info": [
    {
      "payment_method_amount": 250,
      "billing_method": {
        "id": "PT3raaMpFPXEsmVexb5JOF3Zpff2TmtENJ_yZkLTudSrY",
        "save": true
      },
      "line_item_payments": [
        {
          "line_item_id": "aaaaaaaa-0b27-48c7-b682-48e5206e0be3",
          "amount": 150,
          "schedule_remaining": false
        },
        {
          "line_item_id": "bbbbbbbb-0b27-48c7-b682-48e5206e0be3",
          "amount": 100,
          "schedule_remaining": false
        },
      ]
    }
  ]
}

Declined Response:

{
  "success": false,
  "errors": [
    {
      "message": "Declined"
    }
  ]
}

Successful Response:

{
  "success": true,
  "links": [
    {
      "rel": "receipt",
      "href": "/v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/receipt"
    },
    {
      "rel": "unit",
      "href": "/v3/units/300181530"
    }
  ],
  "unit_id": "300181530"
}

Step 6d: Checkout (with existing payment method)

In order to pay with a payment method that exists on the unit’s account (renewal only): first, use the Get Unit Billing Methods API call:

Request:

GET /v3/units/300181530/billing_methods

Response:

{
  "billing_methods": [
    {
      "id": "BM1955320",
      "method": "bank_account",
      "name": "EFT",
      "account_number_last_4_digits": "1111",
      "display_name": "Bank Account (ending in 1111)",
      "expired": false
    }
    {
      "id": "BM1965321",
      "method": "credit_card",
      "name": "MasterCard",
      "account_number_last_4_digits": "5100",
      "display_name": "MasterCard (ending in 5100, expires 1/2022)",
      "expired": false
    }
  ]
}

Now use the id from the previous response in the checkout API call.

Request:

POST /v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/checkout
{
  "version": "AAAAAAmit1o=",
  "customer": {
    "name": "John Doe",
    "email": "john.doe@example.org"
  },
  "payment_info": [
    {
      "payment_method_amount": 250,
      "billing_method": {
        "id": "BM1965321"
      },
      "line_item_payments": [
        {
          "line_item_id": "aaaaaaaa-0b27-48c7-b682-48e5206e0be3",
          "amount": 150,
          "schedule_remaining": false
        },
        {
          "line_item_id": "bbbbbbbb-0b27-48c7-b682-48e5206e0be3",
          "amount": 100,
          "schedule_remaining": false
        },
      ]
    }
  ]
}

Declined Response:

{
  "success": false,
  "errors": [
    {
      "message": "Declined"
    }
  ]
}

Successful Response:

{
  "success": true,
  "links": [
    {
      "rel": "receipt",
      "href": "/v3/membership/2b8a53f2-d482-40f2-a83a-ee5c4d8d8d94/receipt"
    },
    {
      "rel": "unit",
      "href": "/v3/units/300181530"
    }
  ],
  "unit_id": "300181530"
}

Comments